package com.ramblingcoder.bc2.server.tool.update;

import java.io.IOException;
import java.net.Socket;
import java.util.Vector;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import com.ramblingcoder.bc2.server.tool.update.R;
import com.ramblingcoder.bc2.server.tool.update.commands.Parcel;
import com.ramblingcoder.bc2.server.tool.update.commands.SupportingFunctions;
import com.ramblingcoder.bc2.server.tool.update.exceptions.InvalidArguments;
import com.ramblingcoder.bc2.server.tool.update.exceptions.InvalidDuration;
import com.ramblingcoder.bc2.server.tool.update.exceptions.LogInRequired;
import com.ramblingcoder.bc2.server.tool.update.exceptions.TooLongMessage;
import com.ramblingcoder.bc2.server.tool.update.objects.Admin;
import com.ramblingcoder.bc2.server.tool.update.objects.InfoShare;
import com.ramblingcoder.bc2.server.tool.update.objects.Player;

public class ChatView extends Activity implements OnClickListener, OnFocusChangeListener {
	//Variables-----\
	private static final Vector<String[]> chat = new Vector<String[]>(1);
	
	private ScrollView displayWrap;
	
	private LinearLayout display;
	
	private EditText message;
	
	private Button yell;
	private Button say;
    
    private boolean terminate;
    
    private CheckBox kills, teams, joins;
    
    private final Handler mHandler = new Handler();
	//Variables-----/
	
	//Initializer-----\
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
        setContentView(R.layout.chatview);
        
        display = (LinearLayout) findViewById(R.id.displaylayout);
        
        displayWrap = (ScrollView) findViewById(R.id.displaywrap);
        
        message = (EditText) findViewById(R.id.message);
        
        yell = (Button) findViewById(R.id.yell);
        say = (Button) findViewById(R.id.say);
        
        yell.setOnClickListener(this);
        say.setOnClickListener(this);
        message.setOnFocusChangeListener(this);
        
        kills = (CheckBox) findViewById(R.id.kills);
        teams = (CheckBox) findViewById(R.id.teamsquad);
        joins = (CheckBox) findViewById(R.id.joinleave);
        
        repopulateList();
        
        if (chat.size() != 0)
        	addChatMessage("", "Chat View Restored", Color.GREEN, true);
        
        new ChatThread().start();
	}
	
	private void repopulateList() {
		for (String[] args : chat){
			if (args[1].equals("event"))
				addChatEvent(args[2], args[3], false);
			else
				addChatMessage(args[2], args[3], Integer.parseInt(args[0]), false);
		}
	}

	protected void onDestroy() {
		super.onDestroy();

		terminate = true;
		
	}
	
	public boolean onCreateOptionsMenu(Menu menu) {
	    menu.add(1, 5, 0, "Main Menu");
	    menu.add(1, 0, 0, "Clear");
	    menu.add(1, 1, 0, "Players View");
	    menu.add(1, 2, 0, "Ban View");
	    menu.add(1, 3, 0, "Map View");
	    menu.add(1, 4, 0, "Settings View");
	    menu.add(1, 6, 0, "Reserved View");
	    return true;
	}
	
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	    case 5:
	    	finish();
	    	startActivity(new Intent(this, BC2ServerChoice.class));
	    	break;
	    case 0:	
	    	display.removeAllViews();
	    	chat.removeAllElements();
	    	break;
	    case 1:	
	    	finish();
	    	startActivity(new Intent(this, PlayerView.class));
	    	break;
	    case 2:
	    	finish();
	    	startActivity(new Intent(this, BanView.class));
	    	break;
	    case 3:
	    	finish();
	    	startActivity(new Intent(this, MapView.class));
	    	break;
	    case 4:
	    	finish();
	    	startActivity(new Intent(this, SettingsView.class));
	    	break;
	    case 6:
	    	finish();
	    	startActivity(new Intent(this, ReservedView.class));
	    	break;
	    }
	    return true;
	}

    private void addChatEvent(String nameStr, String messageStr) {
    	addChatEvent(nameStr, messageStr, true);
    }
    private void addChatEvent(String nameStr, String messageStr, boolean save) {
    	LinearLayout layout = new LinearLayout(this);
    	layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
    	
    	TextView name = new TextView(this);
    	name.setText(nameStr);
    	name.setTextColor(Color.WHITE);
    	name.setPadding(5, 0, 3, 0);
    	
    	TextView message = new TextView(this);
    	message.setText(messageStr);
    	message.setTextColor(Color.WHITE);
    	message.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));
    	
    	layout.addView(name);
    	layout.addView(message);
    	
    	display.addView(layout);

    	if (save)
			chat.add(new String[]{Color.WHITE+"", "event", nameStr, messageStr});

		displayWrap.fullScroll(ScrollView.FOCUS_DOWN);
	}

    private void addChatMessage(String nameStr, String messageStr, int color) {
    	addChatMessage(nameStr, messageStr, color, true);
    }
    private void addChatMessage(String nameStr, String messageStr, int color, boolean save) {
    	LinearLayout layout = new LinearLayout(this);
    	layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
    	
    	TextView name = new TextView(this);
    	name.setText(nameStr);
    	name.setTextColor(color);
    	name.setPadding(5, 0, 3, 0);
    	
    	TextView message = new TextView(this);
    	message.setText(messageStr);
    	message.setTextColor(Color.WHITE);
    	message.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));
    	
    	layout.addView(name);
    	layout.addView(message);
    	
    	display.addView(layout);

    	if (save)
			chat.add(new String[]{color+"", "message", nameStr, messageStr});

		displayWrap.fullScroll(ScrollView.FOCUS_DOWN);
	}
	//Initializer-----/
	
	//Thread-----\
	String outputName = "";
	String outputMessage = "";
	String outputEvent = "";
	private class ChatThread extends Thread {
		public void run() {
			Socket events = InfoShare.getEvents();
			
	    	while (!terminate){
				try {
					Parcel[] responses = SupportingFunctions.getResponse(events.getInputStream(), true);
					
					System.out.println("---------------------------------------");
					for (Parcel response : responses){
						for (String word : response.getWords())
							System.out.print(word + " | ");
						System.out.println();
						
						if (response.getWords()[0].equalsIgnoreCase("player.onchat")){
							outputName = response.getWords()[1];
							outputMessage = response.getWords()[2];
	
							if (outputName.equals("Server"))
								continue;
							
							mHandler.post(updateChat);
						} else if (response.getWords()[0].equalsIgnoreCase("player.onleave") && joins.isChecked()){
							outputName = response.getWords()[1];
							outputEvent = "has left.";
							
							mHandler.post(updateEvent);
						} else if (response.getWords()[0].equalsIgnoreCase("player.onjoin") && joins.isChecked()){
							outputName = response.getWords()[1];
							outputEvent = "has joined.";
							
							mHandler.post(updateEvent);
						} else if (response.getWords()[0].equalsIgnoreCase("player.onsquadchange") && teams.isChecked()){
							outputName = response.getWords()[1];
							outputEvent = " changed squad to " + Player.SQUADS[Integer.parseInt(response.getWords()[3])] + ".";
							
							mHandler.post(updateEvent);
						} else if (response.getWords()[0].equalsIgnoreCase("player.onteamchange") && teams.isChecked()){
							outputName = response.getWords()[1];
							outputEvent = " changed team to " + Player.TEAMS[Integer.parseInt(response.getWords()[2])] + ".";
							
							mHandler.post(updateEvent);
							
							break;
						} else if (response.getWords()[0].equalsIgnoreCase("player.onkill") && kills.isChecked()){
							if (response.getWords()[1].equals(response.getWords()[2])){
								outputName = response.getWords()[1];
								outputEvent = " comitted suicide.";
							} else {
								outputName = response.getWords()[1];
								outputEvent = " killed " + response.getWords()[2] + ".";
							}
							
							mHandler.post(updateEvent);
						}
					}
					System.out.println("---------------------------------------");
				} catch (IOException e) {
					SupportingFunctions.showError(ChatView.this, e.getMessage(), new Intent(ChatView.this, BC2ServerChoice.class));
				}
			}
    	}
	}

	final Runnable updateChat = new Runnable() {
        public void run() {
        	addChatMessage(outputName, outputMessage, Color.parseColor("#ADD8E6"));
        }
    };
	final Runnable updateEvent = new Runnable() {
        public void run() {
        	addChatEvent(outputName, outputEvent);
        }
    };
	//Thread-----/

	//Events-----\
	public void onClick(View v) {
		if (v.getId() == R.id.yell){
			try {
				String parsedMessage = Admin.yell(InfoShare.getCommand(), message.getText().toString(), 5, "all");
				if (parsedMessage != null)
					addChatMessage("Admin.Yell", parsedMessage, Color.parseColor("#FFA500"));
			} catch (IOException e) {
				SupportingFunctions.showError(this, e.getMessage(), new Intent(this, BC2ServerChoice.class));
			} catch (InvalidArguments e) {
				SupportingFunctions.showError(this, e.getMessage());
			} catch (TooLongMessage e) {
				SupportingFunctions.showError(this, e.getMessage());
			} catch (InvalidDuration e) {
				SupportingFunctions.showError(this, e.getMessage());
			} catch (LogInRequired e) {
				SupportingFunctions.showError(this, e.getMessage(), new Intent(this, BC2ServerChoice.class));
			}

			message.setText("");
		}
		
		if (v.getId() == R.id.say){
			try {
				String parsedMessage = Admin.say(InfoShare.getCommand(), message.getText().toString(), "all");
				if (parsedMessage != null)
					addChatMessage("Admin.Say", parsedMessage.toString(), Color.YELLOW);
			} catch (IOException e) {
				SupportingFunctions.showError(this, e.getMessage(), new Intent(this, BC2ServerChoice.class));
			} catch (InvalidArguments e) {
				SupportingFunctions.showError(this, e.getMessage());
			} catch (TooLongMessage e) {
				SupportingFunctions.showError(this, e.getMessage());
			} catch (LogInRequired e) {
				SupportingFunctions.showError(this, e.getMessage(), new Intent(this, BC2ServerChoice.class));
			}

			message.setText("");
		}
	}

	private boolean cleared = false;
	public void onFocusChange(View v, boolean hasFocus) {
		if (v.getId() == R.id.message){
			if (!cleared){
				message.setText("");
				cleared = true;
			}
		}
	}
    
    public boolean onKeyDown(int keyCode, KeyEvent event)  {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
        	finish();
        	startActivity(new Intent(this, PlayerView.class));
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }
	//Events-----/
    
    public static void clearChat(){
    	chat.removeAllElements();
    }
}
